package utils

import (
	"encoding/binary"
	"fmt"
	"io"
	"net"
)

// 非线程安全的
type Transport struct {
	Conn net.Conn
	Buf  [1024]byte
}

func (transport *Transport) WriteString(data string) (err error) {
	bytes := []byte(data)
	err = transport.WriteUint32(uint32(len(bytes)))
	if err != nil {
		return
	}
	_, err = transport.Conn.Write(bytes)
	if err != nil {
		return
	}
	return
}

func (transport *Transport) WriteBytes(data []byte) (err error) {
	err = transport.WriteUint32(uint32(len(data)))
	if err != nil {
		return
	}
	_, err = transport.Conn.Write(data)
	if err != nil {
		return
	}
	return
}

func (transport *Transport) WriteUint32(data uint32) (err error) {
	var buf [4]byte
	binary.BigEndian.PutUint32(buf[:4], data)
	_, err = transport.Conn.Write(buf[:])
	if err != nil {
		return
	}
	return
}

func (transport *Transport) ReadString() (data string, err error) {

	// 读取字节
	bytes, err := transport.ReadBytes()
	if err != nil {
		return "", err
	}

	return string(bytes), nil
}

func (transport *Transport) ReadBytes() (data []byte, err error) {

	// 读取数据长度
	dataLength, err := transport.ReadUint32()
	if err != nil {
		return nil, err
	}

	// 缓冲区
	buf := make([]byte, dataLength)

	var length = 0

	for {

		// 读取数据
		l, err := transport.Conn.Read(buf[length:4])

		if err == io.EOF {
			return buf, err
		}

		if err != nil {
			fmt.Printf("ReadBytes error=%v\n", err)
			return buf, err
		}

		if l+length >= 4 {
			break
		}

		length = length + l
	}

	return buf, nil
}

func (transport *Transport) ReadUint32() (data int, err error) {

	// 缓冲区
	buf := make([]byte, 4)

	var length = 0

	for {

		// 读取数据
		l, err := transport.Conn.Read(buf[length:4])

		if err == io.EOF {
			return -1, err
		}

		if err != nil {
			fmt.Printf("ReadUint32 error=%v\n", err)
			return -1, err
		}

		if l+length >= 4 {
			break
		}

		length = length + l
	}

	var pkgLen = binary.BigEndian.Uint32(buf[0:4])

	return int(pkgLen), nil
}
